package org.jetlinks.pro.clickhouse.engine;

import lombok.Getter;
import lombok.Setter;
import org.apache.commons.collections4.MapUtils;
import org.hswebframework.web.bean.FastBeanCopier;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;

@Getter
@Setter
public class MergeTree implements Engine {

    private String orderBy;

    private String partitionBy;

    private String primaryKey;

    private String sampleBy;

    private Map<String, String> settings;

    private boolean distributed = false;

    private String cluster;

    public String buildCreateTableSql(String table, String... columns) {
        StringJoiner joiner = new StringJoiner("\n");

        joiner.add("CREATE TABLE IF NOT EXISTS " + table);
        if (distributed && StringUtils.hasText(cluster)) {
            joiner.add(" ON CLUSTER " + cluster);
        }

        StringJoiner columnSQL = new StringJoiner(",\n", "(\n", "\n)");
        for (String column : columns) {
            columnSQL.add(column);
        }

        joiner.add(columnSQL.toString());

        joiner.add("ENGINE = " + getEngine(table));
        if (StringUtils.hasText(orderBy)) {
            joiner.add("ORDER BY " + orderBy);
        }
        if (StringUtils.hasText(partitionBy)) {
            joiner.add("PARTITION BY " + partitionBy);
        }
        if (StringUtils.hasText(primaryKey)) {
            joiner.add("PRIMARY KEY " + primaryKey);
        }
        if (StringUtils.hasText(sampleBy)) {
            joiner.add("SAMPLE BY " + sampleBy);
        }
        if (MapUtils.isNotEmpty(settings)) {
            joiner.add("SETTINGS " + settings
                .entrySet()
                .stream()
                .map(e -> String.join("=", e.getKey(), e.getValue()))
                .collect(Collectors.joining(",")));
        }

        return joiner.toString();
    }

    protected String getEngine(String table) {
        return "MergeTree()";
    }

    public MergeTree orderBy(String orderBy) {
        setOrderBy(orderBy);
        return this;
    }

    public MergeTree partitionBy(String partitionBy) {
       setPartitionBy(partitionBy);
        return this;
    }

    public MergeTree primaryKey(String primaryKey) {
        setPrimaryKey(primaryKey);
        return this;
    }

    public MergeTree sampleBy(String sampleBy) {
       setSampleBy(sampleBy);
        return this;
    }

    public MergeTree settings(Map<String, String> settings) {
       setSettings(settings);
        return this;
    }

    public MergeTree distributed(String cluster) {
        cluster(cluster);
        setDistributed(true);
        return this;
    }

    public MergeTree cluster(String cluster) {
        setCluster(cluster);
        return this;
    }

    public MergeTree copy(){
        return FastBeanCopier.copy(this,new MergeTree());
    }
}
